#ifndef __INC_QGDRAW_H__
#define __INC_QGDRAW_H__

#ifdef _MSC_VER
#pragma once
#endif

//////////////////////////////////////////////////////////////////////////
// buffer

// buffer type
enum qgBufferType
{
	QGBUFFER_UNKNOWN,
	QGBUFFER_INDEX,
	QGBUFFER_VERTEX,
	QGBUFFER_DATA,
};

// flags
#define QGBUFF_PARTICLE						0x0800
#define QGBUFF_STREAM						0x8000

// buffer, abstract
class KAPI qgBuffer : public qgObj
{
	KCH_SUBCLASS(qgBuffer, qgObj);

protected:
	qgBufferType		_buftype;

	kuint				_flags;
	kint				_count;
	kint				_stride;

protected:
	qgBuffer() {}
	~qgBuffer() {}

public:
	virtual kpointer EnterMap(kint flags = 0) = 0;
	virtual bool LeaveMap() = 0;

	qgBufferType GetBufferType() { return _buftype; }
	kint GetFlags(kint mask = 0) { return K_OMASK(_flags, mask); }
	kint GetCount() { return _count; }
	kint GetStride() { return _stride; }

	bool SetIndices(kconstpointer data, kint count = 0, bool is32bit = true);
	bool SetVertices(kconstpointer data, kint count = 0);
};


//////////////////////////////////////////////////////////////////////////
// layout

// element
struct qgLayoutElement
{
	qgDloUsage			usage : 16;
	kint				index : 16;
	qgDloType			type : 16;
	kint				slot : 16;
	kint				insts;

	// internal data
	kint				offset : 16;
	kint				size : 16;
};

// data
struct qgLayoutData : public tpl::MemBase
{
	tpl::Array<qgLayoutElement>	elms;
};

// layout, abstract
class KAPI qgLayout : public qgObj
{
	KCH_SUBCLASS(qgLayout, qgObj);
	KT_DECL_TYPE_INIT(qgLayout);

protected:
	qgLayoutData		_data;

	kint				_stride;
	kushort				_stage[QGSGVERT_MAX_VALUE];

protected:
	qgLayout() {}
	~qgLayout() {}

public:
	const qgLayoutData& GetData() { return _data; }
	kint GetCount() { return _data.elms.Count(); }
	kint GetStride() { return _stride; }
	kint GetStageStride(kint stage) { return (ksize_t)stage < 4 ? _stage[stage] : 0; }
	bool GetElement(kint nth, qgLayoutElement* ret);
	kint FindUsage(qgDloUsage usage);

public:
	static qgLayoutData* _VerifyElements(kint count, const qgLayoutElement* elms);
};

#endif	// __INC_QGDRAW_H__
